﻿// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2009-10-15
//
// Update Date :            
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


enum EF_SPECIFIC_CTRL
{
    eSC_Combo       = 1<<0, // 组合框
    eSC_Edit        = 1<<1, // 单行或多行编辑
};


class FAPI FUI_Frame : public FUI_Object
{
    FUI_DECLARE_CLASS(FUI_Frame)

    friend class FUI_System;
    friend class FUI_Container;
    friend class FUI_SYS_WIDGET;

public:
    FUI_Frame(EF_UI_WIDGET_TYPE t = eUWT_Frame);
    virtual ~FUI_Frame();
    virtual void Release();
    virtual void Render(EF_UI_RENDER_LAYER layer);
    virtual void UpdateRect();
    virtual bool IsChild(FUI_Object* pChild);
    virtual bool PtInObject(funit nX, funit nY);
    virtual FUI_Object* FindObject(funit nX, funit nY);
    virtual void SetVisible(bool visable);
    virtual bool OnKeyDown(unsigned int nChar);
    virtual bool OnKeyUp(unsigned int nChar);
    virtual bool OnChar(unsigned int nChar);
    virtual bool OnMouseMove(funit nX, funit nY);
    virtual bool OnMouseWheel(bool bUp, funit nX, funit nY);
    virtual bool OnLButtonDown(funit nX, funit nY);
    virtual bool OnLButtonUp(funit nX, funit nY);
    virtual bool OnLButtonDBClick(funit nX, funit nY);
    virtual bool OnRButtonDown(funit nX, funit nY);
    virtual bool OnRButtonUp(funit nX, funit nY);

    // 查找子控件
    FUI_Object* FindChild(DWORD nWidgetID);
    // 查找指定类型的所有控件
    void FindChild(EF_UI_WIDGET_TYPE type, FV_UI_POBJECT& vRet);
    // 移动到屏幕正中
    void MoveToCenter();
    // 渲染辅助信息
    void RenderHelper(DWORD color = 0xff00ff00);
    // 跳转某个UI，打开该UI界面，始终返回true
    bool TryJumpUI(FUI_Object* ctrl);
    // 层次发生变化时通知
    void OnFrameLayer(bool enter_top);

    // 取消窗口拖动状态
    FINLINE void CancelDraging(){ bDraging = false; }
    // 窗口是否正在拖动中
    FINLINE bool IsDraging(){ return bDraging; }
    // 子控件数量
    FINLINE size_t GetChildCount(){ return vpChild.size(); }
    // 按索引获取子控件
    FINLINE FUI_Object* GetChild(size_t index){ assert(index >= 0 && index < vpChild.size()); return vpChild[index]; }
    // 能否移动
    FINLINE bool IsCanMobile(){ return pFrameData->IsCanMove(); }
    // 设置能否移动
    FINLINE void SetCanMobile(bool move){ pFrameData->SetCanMove(move); }
    // 是否模式窗口
    FINLINE bool IsModelWnd(){ return (pFrameData->nWorkMode & eUWM_Has_Mode) != 0; }
    // 是否独占窗口
    FINLINE bool IsExclusiveMode(){ return (pFrameData->nWorkMode & eUWM_Has_Exclusive) != 0; }
    // 是否置顶窗口
    FINLINE bool IsTopMode(){ return (pFrameData->nWorkMode & eUWM_Has_Top) != 0; }
    // 是否是底部窗口
    FINLINE bool IsBottom(){ return pFrameData->nWorkMode == eUWM_Bottom; }
    // 获取工作模式标记
    FINLINE EF_UI_WORK_MODE GetWorkMode(){ return (EF_UI_WORK_MODE)pFrameData->nWorkMode; }
    // 设置工作模式标记
    FINLINE void SetWorkMode(EF_UI_WORK_MODE wm){ pFrameData->nWorkMode = (BYTE)wm; }
    // 是否是动态创建型的，否则是单实例的
    FINLINE bool IsDynamic(){ return pFrameData->IsDynamic(); }
    // 最大化状态
    FINLINE void SetShowMax(bool v){ pFrameData->SetShowMax(v); NeedUpdateRect(); }
    FINLINE bool IsShowMax(){ return pFrameData->IsShowMax(); }
    // 设置与获取当前界面的拥有特殊控件状态标记
    FINLINE void AddSpecCtrl(EF_SPECIFIC_CTRL prop){ byHasSpecCtrl |= prop; }
    FINLINE void SubSpecCtrl(EF_SPECIFIC_CTRL prop){ byHasSpecCtrl &= ~prop; }
    FINLINE bool HasSpecCtrl(EF_SPECIFIC_CTRL prop){ return (byHasSpecCtrl & prop) != 0; }
    FINLINE void SetSpecCtrl(EF_SPECIFIC_CTRL prop, bool vl){ if (vl) AddSpecCtrl(prop); else SubSpecCtrl(prop); }

private:
    virtual void InitUIData(FUI_Object* father, fuWidgetBase* pData, FUI_Layout* layout);
    virtual void Update();

    WORD LoadUIFromFile(const WCHAR* szFileName, FUI_Layout* layout);
    WORD LoadUIFromFile(const ACHAR* szFileName, FUI_Layout* layout);
    WORD LoadUIFromMemory(BYTE* mem, size_t size, const WCHAR* name, FUI_Layout* layout);
    WORD LoadUIFromMemory(BYTE* mem, size_t size, const ACHAR* name, FUI_Layout* layout);
    WORD LoadUIFromWDF(FUIWidgetDataFile& wdf, FUI_Layout* layout);
    WORD FinishLoad(FUI_Layout* layout);

public:
    static void AppendChild(FV_UI_POBJECT& vp, FUI_Frame* frame, FUI_Object* pChlid);

protected:
    fuWidgetFrame* pFrameData;
    FUIWidgetDataFile uWidgetUseData; // 控件的使用数据(游戏过程中可能会变化)
    bool bEntiretyCover;    // 完全被其它UI框架遮挡(与是否可见不同，此值仅UI系统使用)
    bool bDraging;          // 框架是否拖动中
    fuPoint nDragOffset;    // 拖动时的偏移
    BYTE byHasSpecCtrl;     // 本界面的特殊控件表
    FV_UI_POBJECT vpChild;
};